package com.moss.cloud.remote.biz.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.moss.cloud.common.core.exception.BaseException;
import com.moss.cloud.common.core.exception.SystemErrorType;
import com.moss.cloud.common.core.utils.HttpUtil;
import com.moss.cloud.remote.api.model.vo.WXCodeAccessToken;
import com.moss.cloud.remote.api.model.vo.WXUserInfo;
import com.moss.cloud.remote.api.model.vo.WXUserJSCode;
import com.moss.cloud.remote.api.model.vo.WXUserToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import java.util.function.Consumer;

/**
 * 微信工具类
 *
 * @author 瑾年
 * @date 2023年3月28日
 */
@Slf4j
public class WXUtil {
    private static final String JS_CODE2_SESSION = "https://api.weixin.qq.com/sns/jscode2session";
    private static final String WX_TOKEN = "https://api.weixin.qq.com/cgi-bin/token";
    // 获取微信用户access_token的接口地址
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";
    // 获取微信用户信息的接口地址
    private static final String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo";
    private static final String ERR_CODE = "errcode";
    private static final String ERR_MSG = "errmsg";
    private static final String ACCESS_TOKEN = "access_token";
    private static final int ZERO_CODE = 0;
    private static final String OPENID = "openid";

    /**
     * JS_CODE获取openid
     *
     * @param appId
     * @param code
     * @param secret
     * @return
     */
    public static WXUserJSCode doGet(String appId, String code, String secret) {
        String wxJsCodeUrl = JS_CODE2_SESSION + "?appid=" + appId + "&secret=" + secret +
                "&js_code=" + code + "&grant_type=authorization_code";
        String result = buildWebClient(wxJsCodeUrl);
        String jsonStr = parseResult(result,OPENID);
        WXUserJSCode wxUserJSCode = JSON.parseObject(jsonStr, WXUserJSCode.class);
        return wxUserJSCode;
    }

    /**
     * appId secret 获取 access_token
     *
     * @param appId
     * @param secret
     * @return
     */
    public static WXUserToken doGet(String appId, String secret) {
        String wxTokenUrl = WX_TOKEN + "?grant_type=client_credential&appid=" + appId + "&secret=" + secret + "";
        String result = buildWebClient(wxTokenUrl);
        String jsonStr = parseResult(result, ACCESS_TOKEN);
        WXUserToken wxUserToken = JSON.parseObject(jsonStr, WXUserToken.class);
        return wxUserToken;
    }

    /**
     * 用CODE换取access_token
     *
     * @param appId
     * @param secret
     * @param code
     * @return
     */
    public static WXCodeAccessToken doGetToken(String appId, String secret, String code) {
        String url = ACCESS_TOKEN_URL + "?appid=" + appId + "&secret=" + secret + "&code=" + code
                + "&grant_type=authorization_code";
        String result = buildWebClient(url);
        String jsonStr = parseResult(result, ACCESS_TOKEN);
        WXCodeAccessToken wxCodeAccessToken = JSON.parseObject(jsonStr, WXCodeAccessToken.class);
        return wxCodeAccessToken;
    }

    /**
     * 用accessToken和openid获取用户信息
     *
     * @param accessToken
     * @param openid
     * @return
     */
    public static WXUserInfo doGetUserInfo(String accessToken, String openid) {
        String url = USER_INFO_URL + "?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
        String result = buildWebClient(url);
        String jsonStr = parseResult(result, OPENID);
        WXUserInfo wxUserInfo = JSON.parseObject(jsonStr, WXUserInfo.class);
        return wxUserInfo;
    }

    /**
     * 构建WebClient请求
     *
     * @param url
     * @return
     */
    public static String buildWebClient(String url) {
        Consumer<HttpHeaders> consumer = httpHeaders -> {};
        return HttpUtil.doGet(url,consumer);
    }

    /**
     * 解析获取 access_token结果
     *
     * @param result
     * @return
     */
    public static String parseResult(String result, String key) {
        JSONObject jsonObject = JSONObject.parseObject(result);
        log.info("调用微信接口返回结果:{}", jsonObject);
        if (!jsonObject.containsKey(key)) {
            log.error("调用微信接口异常->错误码:{},错误信息:{}", jsonObject.get(ERR_CODE), jsonObject.get(ERR_MSG));
            throw new BaseException(SystemErrorType.WX_FAIL);
        }
        return jsonObject.toJSONString();
    }


    public static void main(String[] args) {
        WXUserJSCode wxUserJSCode = doGet("wx6589542b424acc83","0d3Xx1000MJXHP15gj300FWUUT3Xx10d","7d53c91620e61307c6ea4f8664a2856f");
        WXUserToken wxUserToken = doGet("wx6589542b424acc83","7d53c91620e61307c6ea4f8664a2856f");
        WXUserInfo wxUserInfo = doGetUserInfo(wxUserToken.getAccess_token(),
                wxUserJSCode.getOpenid());
        System.out.println(wxUserInfo);
    }
}
